(function($){

    // closeDOMWindow
    $.fn.closeDOMWindow = function(settings){
        if(!settings){settings={};}
        var run = function(passingThis){
            var $DOMWindowOverlay = $('#modal-overlay');
            var $DOMWindow = $('#modal-window');
            $DOMWindowOverlay.fadeOut('fast',function(){
                $DOMWindowOverlay.trigger('unload').unbind().remove();
            });
            $DOMWindow.fadeOut('fast',function(){
                $DOMWindow.trigger("unload").remove();
            });
            $(window).unbind('scroll.DOMWindow');
            $(window).unbind('resize.DOMWindow');
            if(settings.functionCallOnClose){settings.functionCallAfterClose();}    
        };
        if(settings.eventType){ // if used with $().
            return this.each(function(index){
                $(this).bind(settings.eventType, function(){
                    run(this);
                    return false;
                });
            });
        }else{ // else called as $.function
            run();
        } 
    };

    // allow for public call, pass settings
    $.closeDOMWindow = function(s){$.fn.closeDOMWindow(s);};

    // openDOMWindow
    $.fn.openDOMWindow = function(instanceSettings){
        var shortcut =  $.fn.openDOMWindow;

        // default settings combined with callerSettings

        shortcut.defaultsSettings = {
            eventType: null, // options: click, blur, change, dblclick, error, focus, load, mousedown, mouseout, mouseup etc...
            functionCallOnOpen: null,
            functionCallOnClose: null,
            loader: 1, 
            windowHTTPType: 'get',
            windowSource: 'inline', // options: inline, ajax, iframe
            windowSourceID: '',
            windowSourceURL: '',
            windowSourceAttrURL: 'href'
        };

        var settings = $.extend({}, $.fn.openDOMWindow.defaultsSettings , instanceSettings || {});

        // private functions

        var sizeOverlay = function(){
            var $DOMWindowOverlay = $('#modal-overlay');
            $DOMWindowOverlay.css({'position':'fixed'});    
        };

        var centerLoader = function() {
            var $DOMWindowLoader = $('#modal-loader');
            $DOMWindowLoader.css({'position':'fixed'});
        };

        var showDOMWindow = function(instance){
            if(arguments[0]){
                $('.'+instance+' #modal-loader').remove();
                $('.'+instance+' #DOMWindowContent').fadeIn('fast',function(){if(settings.functionCallOnOpen){settings.functionCallOnOpen();}});
                $('.'+instance+ '.modal-window-close').click(function(){
                    $.closeDOMWindow();    
                    return false;
                });
            }else{
                $('#modal-loader').remove();
                $('#modal-window').fadeIn('fast',function(){if(settings.functionCallOnOpen){settings.functionCallOnOpen();}});
                $('#modal-window .modal-window-close').click(function(){                        
                    $.closeDOMWindow();
                    return false;
                });
            }

        };

        var urlQueryToObject = function(s){
              var query = {};
              s.replace(/b([^&=]*)=([^&=]*)b/g, function (m, a, d) {
                if(typeof query[a] != 'undefined') {
                  query[a] += ',' + d;
                }else{
                  query[a] = d;
                }
              });
              return query;
        };

        // run routine
        var run = function(passingThis){
            
            // get values from element clicked, or assume its passed as an option
            settings.windowSourceID = $(passingThis).attr('href') || settings.windowSourceID;
            settings.windowSourceURL = $(passingThis).attr(settings.windowSourceAttrURL) || settings.windowSourceURL;
            var urlOnly, urlQueryObject;

            // overlay
            $('body').append('<div id="modal-overlay" style="display:none;"></div>');
            sizeOverlay();
            var $DOMWindowOverlay = $('#modal-overlay');
            $DOMWindowOverlay.fadeIn('fast');

            // loader
            if(settings.loader !== ''){
                $('body').append('<div id="modal-loader" style="z-index:10002;"></div>');
                centerLoader();
            }

            // add DOMwindow
            if(settings.windowSource == 'iframe'){
                $('body').append('<div id="modal-window" style="display:none;"></div>');
            }else{
                $('body').append('<div id="modal-window" style="display:none;"><a href="#" class="modal-window-close" title="Close">Close</a><div id="modal-window-inner" style="overflow:auto;"></div></div>');
            }
            
            var $DOMWindow = $('#modal-window');
            var $DOMWindowInner = $('#modal-window-inner');

            switch(settings.windowSource){
                // add inline content
                case 'inline':
                    $DOMWindowInner.append($(settings.windowSourceID).children());
                    $DOMWindow.unload(function(){ // move elements back when you're finished
                        $(settings.windowSourceID).append($DOMWindowInner.children());
                    });
                    showDOMWindow();
                break;
                // add iframe content
                case 'iframe':
                    $DOMWindow.append('<a href="#" class="modal-window-close" title="Close">Close</a><iframe id="modal-iframe" frameborder="0" hspace="0" wspace="0" src="'+settings.windowSourceURL+'" name="modal-iframe'+Math.round(Math.random()*1000)+'" style="overflow:auto;"></iframe>');
                    $('#modal-iframe').load(showDOMWindow());
                break;
                // add ajax content
                case 'ajax':
                    if(settings.windowHTTPType == 'post'){
                        
                        if(settings.windowSourceURL.indexOf("?") !== -1){ // has a query string
                            urlOnly = settings.windowSourceURL.substr(0, settings.windowSourceURL.indexOf("?"));
                            urlQueryObject = urlQueryToObject(settings.windowSourceURL);
                        }else{
                            urlOnly = settings.windowSourceURL;
                            urlQueryObject = {};
                        }
                        $DOMWindowInner.load(urlOnly,urlQueryObject,function(){
                            showDOMWindow();
                        });
                    }else{
                        if(settings.windowSourceURL.indexOf("?") == -1){ // no query string, so add one
                            settings.windowSourceURL += '?';
                        }
                        $DOMWindowInner.load(
                            settings.windowSourceURL + '&random=' + (new Date().getTime()),function(){
                            showDOMWindow();
                        });
                    }
                break;
            }

        }; // end run()
        
        if(settings.eventType){ // if used with $().
            return this.each(function(index){                  
                $(this).bind(settings.eventType,function(){
                    run(this);
                    return false;
                });
            });
        }else{ // else called as $.function
            run();
        }

    }; // end function openDOMWindow

    // allow for public call, pass settings
    $.openDOMWindow = function(s){$.fn.openDOMWindow(s);};

})(jQuery);
